/**
 * @file test_moparse.cpp
 * @brief moparse功能测试用例
 */

#include "../moparse.h"
#include <iostream>
#include <fstream>
#include <cassert>
#include <functional>
#include <cstdio>

class TestRunner {
public:
    TestRunner() : tests_passed_(0), tests_failed_(0) {}
    
    void run_test(const std::string& test_name, std::function<bool()> test_func) {
        std::cout << "运行测试: " << test_name << " ... ";
        try {
            if (test_func()) {
                std::cout << "通过" << std::endl;
                tests_passed_++;
            } else {
                std::cout << "失败" << std::endl;
                tests_failed_++;
            }
        } catch (const std::exception& e) {
            std::cout << "异常: " << e.what() << std::endl;
            tests_failed_++;
        }
    }
    
    void print_summary() {
        std::cout << "\n测试总结:" << std::endl;
        std::cout << "通过: " << tests_passed_ << std::endl;
        std::cout << "失败: " << tests_failed_ << std::endl;
        std::cout << "总计: " << (tests_passed_ + tests_failed_) << std::endl;
    }
    
    int get_failed_count() const { return tests_failed_; }

private:
    int tests_passed_;
    int tests_failed_;
};

// 创建测试用的Verilog文件
void create_test_verilog_files() {
    // 创建简单的测试模块
    std::ofstream simple_file("test_simple.v");
    simple_file << R"(
// 简单测试模块
module simple_counter (
    input clk,
    input reset,
    input enable,
    output reg [7:0] count
);

parameter MAX_COUNT = 255;
parameter MIN_COUNT = 0;

wire clk_enable;
wire reset_sync;

assign clk_enable = clk & enable;
assign reset_sync = reset;

always @(posedge clk or posedge reset) begin
    if (reset)
        count <= MIN_COUNT;
    else if (enable)
        count <= (count == MAX_COUNT) ? MIN_COUNT : count + 1;
end

endmodule
)";
    simple_file.close();

    // 创建包含实例的复杂模块
    std::ofstream complex_file("test_complex.v");
    complex_file << R"(
// 复杂测试模块
module top_module (
    input clk,
    input reset,
    input [3:0] data_in,
    output [7:0] data_out,
    output valid
);

parameter DATA_WIDTH = 8;
parameter ADDR_WIDTH = 4;

wire [DATA_WIDTH-1:0] fifo_data;
wire fifo_empty, fifo_full;
wire [ADDR_WIDTH-1:0] read_addr, write_addr;

// FIFO实例
fifo_module #(
    .DATA_WIDTH(DATA_WIDTH),
    .DEPTH(16)
) u_fifo (
    .clk(clk),
    .reset(reset),
    .data_in(data_in),
    .write_enable(~fifo_full),
    .read_enable(~fifo_empty),
    .data_out(fifo_data),
    .empty(fifo_empty),
    .full(fifo_full)
);

// 计数器实例
simple_counter u_counter (
    .clk(clk),
    .reset(reset),
    .enable(~fifo_empty),
    .count(read_addr)
);

assign data_out = fifo_data;
assign valid = ~fifo_empty;

endmodule

// FIFO模块定义
module fifo_module #(
    parameter DATA_WIDTH = 8,
    parameter DEPTH = 16
) (
    input clk,
    input reset,
    input [DATA_WIDTH-1:0] data_in,
    input write_enable,
    input read_enable,
    output reg [DATA_WIDTH-1:0] data_out,
    output empty,
    output full
);

reg [DATA_WIDTH-1:0] memory [0:DEPTH-1];
reg [$clog2(DEPTH):0] write_ptr, read_ptr;

assign empty = (write_ptr == read_ptr);
assign full = ((write_ptr + 1) % DEPTH == read_ptr);

always @(posedge clk or posedge reset) begin
    if (reset) begin
        write_ptr <= 0;
        read_ptr <= 0;
        data_out <= 0;
    end else begin
        if (write_enable && !full) begin
            memory[write_ptr] <= data_in;
            write_ptr <= (write_ptr + 1) % DEPTH;
        end
        
        if (read_enable && !empty) begin
            data_out <= memory[read_ptr];
            read_ptr <= (read_ptr + 1) % DEPTH;
        end
    end
end

endmodule
)";
    complex_file.close();

    // 创建文件列表
    std::ofstream filelist("verilog.list");
    filelist << "test_simple.v\n";
    filelist << "test_complex.v\n";
    filelist.close();
}

// 清理测试文件
void cleanup_test_files() {
    std::vector<std::string> files = {
        "test_simple.v", "test_complex.v", "verilog.list",
        "test_output.modb", "test_merge.modb", "test_existing.modb",
        "empty_test.v", "stub_test.v", "full_test.v", "instance_test.v",  // 新增反向生成文件
        "main_filelist.list", "sub_filelist.list", "another_sub.list",  // 新增嵌套文件列表
        "test_nested.modb", "circular1.list", "circular2.list"  // 新增循环测试文件
    };
    
    for (const auto& file : files) {
        std::remove(file.c_str());
    }
}

// 测试基本解析功能
bool test_basic_parsing() {
    VerilogParser parser;
    
    // 解析简单模块
    if (!parser.parseVerilogFile("test_simple.v")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    if (db.modules_size() != 1) {
        return false;
    }
    
    const auto& module = db.modules(0);
    if (module.name() != "simple_counter") {
        return false;
    }
    
    // 检查端口数量
    if (module.ports_size() < 4) {
        return false;
    }
    
    // 检查参数数量
    if (module.parameters_size() < 2) {
        return false;
    }
    
    return true;
}

// 测试文件保存和加载
bool test_save_load() {
    VerilogParser parser;
    
    // 解析并保存
    if (!parser.parseVerilogFile("test_simple.v")) {
        return false;
    }
    
    if (!parser.saveToModb("test_output.modb")) {
        return false;
    }
    
    // 创建新的解析器并加载
    VerilogParser loader;
    if (!loader.loadFromModb("test_output.modb")) {
        return false;
    }
    
    const auto& db = loader.getDatabase();
    if (db.modules_size() != 1) {
        return false;
    }
    
    if (db.modules(0).name() != "simple_counter") {
        return false;
    }
    
    return true;
}

// 测试文件列表解析
bool test_file_list_parsing() {
    VerilogParser parser;
    
    if (!parser.parseVerilogFileList("verilog.list")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    
    // 应该解析出多个模块
    if (db.modules_size() < 2) {
        return false;
    }
    
    // 检查是否包含期望的模块
    bool has_simple = false;
    bool has_complex = false;
    
    for (const auto& module : db.modules()) {
        if (module.name() == "simple_counter") {
            has_simple = true;
        } else if (module.name() == "top_module" || module.name() == "fifo_module") {
            has_complex = true;
        }
    }
    
    return has_simple && has_complex;
}

// 测试模块合并
bool test_module_merge() {
    VerilogParser parser1;
    VerilogParser parser2;
    
    // 解析第一个文件并保存
    if (!parser1.parseVerilogFile("test_simple.v")) {
        return false;
    }
    
    if (!parser1.saveToModb("test_existing.modb")) {
        return false;
    }
    
    // 解析第二个文件并合并
    if (!parser2.parseVerilogFile("test_complex.v")) {
        return false;
    }
    
    if (!parser2.mergeToExistingModb("test_existing.modb")) {
        return false;
    }
    
    // 验证合并结果
    VerilogParser loader;
    if (!loader.loadFromModb("test_existing.modb")) {
        return false;
    }
    
    const auto& db = loader.getDatabase();
    return db.modules_size() >= 2;
}

// 测试指定模块解析
bool test_specific_module_parsing() {
    VerilogParser parser;
    
    // 只解析指定模块
    if (!parser.parseVerilogFile("test_complex.v", "fifo_module")) {
        return false;
    }
    
    const auto& db = parser.getDatabase();
    if (db.modules_size() != 1) {
        return false;
    }
    
    if (db.modules(0).name() != "fifo_module") {
        return false;
    }
    
    return true;
}

// 测试模块删除
bool test_module_deletion() {
    VerilogParser parser;
    
    // 解析多个模块并保存
    if (!parser.parseVerilogFileList("verilog.list")) {
        return false;
    }
    
    if (!parser.saveToModb("test_merge.modb")) {
        return false;
    }
    
    // 删除一个模块
    if (!parser.deleteModule("test_merge.modb", "simple_counter")) {
        return false;
    }
    
    // 验证删除结果
    VerilogParser loader;
    if (!loader.loadFromModb("test_merge.modb")) {
        return false;
    }
    
    const auto& db = loader.getDatabase();
    
    // 检查模块是否被删除
    for (const auto& module : db.modules()) {
        if (module.name() == "simple_counter") {
            return false; // 模块应该已被删除
        }
    }
    
    return true;
}

// 测试错误处理
bool test_error_handling() {
    VerilogParser parser;
    
    // 测试不存在的文件
    if (parser.parseVerilogFile("nonexistent.v")) {
        return false; // 应该失败
    }
    
    // 测试不存在的.modb文件
    if (parser.loadFromModb("nonexistent.modb")) {
        return false; // 应该失败
    }
    
    return true;
}

// 测试嵌套文件列表功能
bool test_nested_filelist() {
    // 创建嵌套文件列表结构
    std::ofstream main_list("main_filelist.list");
    main_list << "# 主文件列表\n";
    main_list << "test_simple.v\n";
    main_list << "-f sub_filelist.list\n";
    main_list << "test_complex.v\n";
    main_list.close();
    
    std::ofstream sub_list("sub_filelist.list");
    sub_list << "# 子文件列表\n";
    sub_list << "-f another_sub.list\n";  // 再次嵌套
    sub_list.close();
    
    std::ofstream another_list("another_sub.list");
    another_list << "# 另一个子文件列表\n";
    another_list << "test_simple.v\n";  // 重复文件，测试去重
    another_list.close();
    
    VerilogParser parser;
    
    // 测试嵌套解析
    if (!parser.parseVerilogFileList("main_filelist.list")) {
        return false;
    }
    
    // 验证解析结果
    const auto& db = parser.getDatabase();
    if (db.modules_size() < 2) {  // 应该至少有两个模块
        return false;
    }
    
    // 保存结果用于进一步验证
    if (!parser.saveToModb("test_nested.modb")) {
        return false;
    }
    
    return true;
}

// 测试循环引用检测
bool test_circular_reference() {
    // 创建循环引用的文件列表
    std::ofstream circular1("circular1.list");
    circular1 << "-f circular2.list\n";
    circular1.close();
    
    std::ofstream circular2("circular2.list");
    circular2 << "-f circular1.list\n";
    circular2.close();
    
    VerilogParser parser;
    
    // 应该能够检测到循环引用并防止死循环
    bool result = parser.parseVerilogFileList("circular1.list");
    
    // 返回true表示没有死循环，成功处理了循环引用
    return result;
}

// 测试反向生成功能
bool test_reverse_generation() {
    VerilogParser parser;
    
    // 首先解析一个模块
    if (!parser.parseVerilogFile("test_simple.v")) {
        return false;
    }
    
    if (!parser.saveToModb("test_reverse.modb")) {
        return false;
    }
    
    // 测试生成空壳模块
    if (!parser.generateVerilog("test_reverse.modb", "simple_counter", "empty_test.v", "e")) {
        return false;
    }
    
    // 测试生成stub模块
    if (!parser.generateVerilog("test_reverse.modb", "simple_counter", "stub_test.v", "es")) {
        return false;
    }
    
    // 测试生成完整模块
    if (!parser.generateVerilog("test_reverse.modb", "simple_counter", "full_test.v", "a")) {
        return false;
    }
    
    // 测试生成实例代码
    if (!parser.generateVerilog("test_reverse.modb", "simple_counter", "instance_test.v", "i")) {
        return false;
    }
    
    // 验证文件是否生成
    std::ifstream emptyFile("empty_test.v");
    std::ifstream stubFile("stub_test.v");
    std::ifstream fullFile("full_test.v");
    std::ifstream instanceFile("instance_test.v");
    
    if (!emptyFile.is_open() || !stubFile.is_open() || 
        !fullFile.is_open() || !instanceFile.is_open()) {
        return false;
    }
    
    // 简单验证文件内容
    std::string emptyContent;
    std::getline(emptyFile, emptyContent);
    if (emptyContent.find("module simple_counter") == std::string::npos) {
        return false;
    }
    
    std::string stubContent;
    std::getline(stubFile, stubContent);
    if (stubContent.find("module simple_counter") == std::string::npos) {
        return false;
    }
    
    std::string instanceContent;
    std::getline(instanceFile, instanceContent);
    if (instanceContent.find("simple_counter") == std::string::npos) {
        return false;
    }
    
    // 清理测试文件
    std::remove("test_reverse.modb");
    
    return true;
}

int main() {
    std::cout << "开始moparse功能测试...\n" << std::endl;
    
    // 创建测试文件
    create_test_verilog_files();
    
    TestRunner runner;
    
    // 运行测试
    runner.run_test("基本解析功能", test_basic_parsing);
    runner.run_test("文件保存和加载", test_save_load);
    runner.run_test("文件列表解析", test_file_list_parsing);
    runner.run_test("模块合并", test_module_merge);
    runner.run_test("指定模块解析", test_specific_module_parsing);
    runner.run_test("模块删除", test_module_deletion);
    runner.run_test("错误处理", test_error_handling);
    runner.run_test("嵌套文件列表", test_nested_filelist);
    runner.run_test("循环引用检测", test_circular_reference);
    runner.run_test("反向生成功能", test_reverse_generation);
    
    // 清理测试文件
    cleanup_test_files();
    
    // 输出测试结果
    runner.print_summary();
    
    return runner.get_failed_count() > 0 ? 1 : 0;
}